﻿using System;
using BSU.Math.Geometry;

namespace BSU.Math.Algebra
{
    public class Vector
    {
        #region Private fieds

        protected double[] _a;

        #endregion

        #region Properties

        public int M { get; protected set; }

        #endregion

        #region Constructors and initializers

        protected Vector()
        {
        }

        public Vector(int m)
        {
            M = m;

            _a = new double[M];
        }

        public Vector(Vector v)
            : this(v.M)
        {
            for (var i = 0; i < v.M; i++)
            {
                this[i] = v[i];
            }
        }

        public Vector(Point4D point)
            : this(4)
        {
            this[0] = point.X;
            this[1] = point.Y;
            this[2] = point.Z;
            this[3] = point.U;
        }

        #endregion

        #region Operators

        public double this[int i]
        {
            get
            {
                return _a[i];
            }
            set
            {
                _a[i] = value;
            }
        }

        public static Vector operator +(Vector a, Vector b)
        {
            if (a.M != b.M)
            {
                throw new ArgumentException("Cannot perform operation with vectors with given size.");
            }

            var c = new Vector(a.M);

            for (var i = 0; i < a.M; i++)
            {
                c[i] = a[i] + b[i];
            }
            return c;
        }

        public static Vector operator -(Vector a, Vector b)
        {
            if (a.M != b.M)
            {
                throw new ArgumentException("Cannot perform operation with vectors with given size.");
            }

            var c = new Vector(a.M);

            for (var i = 0; i < a.M; i++)
            {
                c[i] = a[i] - b[i];
            }

            return c;
        }

        public double Norm()
        {
            double summ = 0;

            for (var i = 0; i < M; i++)
            {
                summ += this[i] * this[i];
            }

            return System.Math.Sqrt(summ);
        }

        //public static Matrix operator *(Matrix a, double k)
        //{
        //    Matrix c = new Matrix(a.M, a.N);

        //    for (int i = 0; i < a.M; i++)
        //    {
        //        for (int j = 0; j < a.N; j++)
        //        {
        //            c[i, j] = a[i, j] * k;
        //        }
        //    }

        //    return c;
        //}

        //public static Matrix operator *(double k, Matrix a)
        //{
        //    Matrix c = new Matrix(a.M, a.N);

        //    for (int i = 0; i < a.M; i++)
        //    {
        //        for (int j = 0; j < a.N; j++)
        //        {
        //            c[i, j] = a[i, j] * k;
        //        }
        //    }

        //    return c;
        //}

        //public static Matrix operator *(Matrix a, Matrix b)
        //{
        //    if (a.N != b.M)
        //    {
        //        throw new ApplicationException("Cannot perform operation with matrices with given size.");
        //    }

        //    Matrix c = new Matrix(a.M, b.N);

        //    for (int i = 0; i < a.M; i++)
        //    {
        //        for (int j = 0; j < b.N; j++)
        //        {
        //            for (int k = 0; k < a.N; k++)
        //            {
        //                c[i, j] += a[i, k] * b[k, j];
        //            }
        //        }
        //    }

        //    return c;
        //}

        #endregion
    }
}